package labox.innovation.gameserver.skills;

import java.io.File;
import java.util.List;
import java.util.Map;

import javolution.util.FastList;
import javolution.util.FastMap;
import labox.innovation.config.Config;
import labox.innovation.gameserver.Item;
import labox.innovation.gameserver.skills.DocumentSkill.Skill;
import labox.innovation.gameserver.skills.conditions.Condition;
import labox.innovation.gameserver.templates.StatsSet;
import labox.innovation.gameserver.templates.item.L2Armor;
import labox.innovation.gameserver.templates.item.L2ArmorType;
import labox.innovation.gameserver.templates.item.L2EtcItem;
import labox.innovation.gameserver.templates.item.L2EtcItemType;
import labox.innovation.gameserver.templates.item.L2Item;
import labox.innovation.gameserver.templates.item.L2Weapon;
import labox.innovation.gameserver.templates.item.L2WeaponType;

import org.w3c.dom.Document;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;    
import org.w3c.dom.Element;

/**
 * ��Ʒ���� ������
 * 
 * @author zjj
 *
 */
//������Ʒ�������
final class DocumentItem extends DocumentBase
{
    private Item _currentItem = null;
    private List<L2Item> _itemsInFile = new FastList<L2Item>();
    private int	_iDentify;
    
    // add

	private static final Map<String, L2WeaponType> _weaponTypes = new FastMap<String, L2WeaponType>();

	private static final Map<String, L2ArmorType> _armorTypes = new FastMap<String, L2ArmorType>();
	
	private static final Map<String, L2EtcItemType> _etcTypes = new FastMap<String, L2EtcItemType>();

	private static final Map<String, Integer> _slots = new FastMap<String, Integer>();
	
	private static final Map<String, Integer> _pcPropertys = new FastMap<String, Integer>();
	
	
	static {
		
		//�������� ״̬��  ���ܻ������װ���ϵ� ����
		_pcPropertys.put("mDef",  1);
		_pcPropertys.put("pDef",  2);
		//
		
		_weaponTypes.put("none", L2WeaponType.NONE); // these are shields !  
		_weaponTypes.put("sword", L2WeaponType.SWORD);
		_weaponTypes.put("knife", L2WeaponType.KNIFE);
		_weaponTypes.put("fan", L2WeaponType.FAN);
		_weaponTypes.put("axe", L2WeaponType.AXE);
		_weaponTypes.put("claw", L2WeaponType.CLAW);
		_weaponTypes.put("staffs", L2WeaponType.STAFFS); //����
		_weaponTypes.put("pet", L2WeaponType.PET); //Pet Weapon   

		
		_armorTypes.put("breastplate", L2ArmorType.BREASTPLATE); //�ؼ�
		_armorTypes.put("pauldron", L2ArmorType.PAULDRON);  //����
		_armorTypes.put("pants", L2ArmorType.PANTS); //�ȼ�
		_armorTypes.put("shoe", L2ArmorType.SHOE);   //Ь��
		_armorTypes.put("helmet", L2ArmorType.HELMET);  //ͷ��
		_armorTypes.put("necklace", L2ArmorType.NECKLACE); //����
		_armorTypes.put("bracer", L2ArmorType.BREACER); //����
		_armorTypes.put("ring", L2ArmorType.RING);		//��ָ
		_armorTypes.put("jade", L2ArmorType.JADE);		 //����
		_armorTypes.put("talisman", L2ArmorType.TAILSMAN);  //����
		_armorTypes.put("wing", L2ArmorType.WING); //���

		
		_etcTypes.put("RedPotion", L2EtcItemType.REDPOTION);
		_etcTypes.put("BluePotion", L2EtcItemType.BLUEPOTION);
		_etcTypes.put("PurplePotion", L2EtcItemType.PURPLEPOTION);
		_etcTypes.put("GreenPotion", L2EtcItemType.GREENPOTION);
		_etcTypes.put("StarStone", L2EtcItemType.STARSTONE);
		_etcTypes.put("ComposeStone", L2EtcItemType.COMPOSESTONE);
		_etcTypes.put("Scroll", L2EtcItemType.SCROLL);
		_etcTypes.put("Quest", L2EtcItemType.QUEST);
		_etcTypes.put("Money", L2EtcItemType.MONEY);
		_etcTypes.put("Spellbook", L2EtcItemType.SPELLBOOK);
		_etcTypes.put("Jewel", L2EtcItemType.JEWEL);
		_etcTypes.put("chests", L2EtcItemType.CHESTS);
		_etcTypes.put("retalents", L2EtcItemType.RETALENTS);
		_etcTypes.put("StoreExp", L2EtcItemType.STOREEXP);

		_slots.put("lbracelet", L2Item.SLOT_L_BRACELET); //����
		_slots.put("rbracelet", L2Item.SLOT_R_BRACELET); //�һ���
		_slots.put("rbracelet,lbracelet", L2Item.SLOT_L_BRACELET | L2Item.SLOT_R_BRACELET );	
		
		_slots.put("talisman", L2Item.SLOT_DECO);  //����
		_slots.put("chest", L2Item.SLOT_CHEST);    //�ز�
		_slots.put("shoulder", L2Item.SLOT_SHOULDER); //�粿

		_slots.put("head", L2Item.SLOT_HEAD);      //ͷ��

//		_slots.put("underwear", L2Item.SLOT_UNDERWEAR); //����
//		_slots.put("back", L2Item.SLOT_BACK);    //����
		_slots.put("neck", L2Item.SLOT_NECK);    //����
		_slots.put("legs", L2Item.SLOT_LEGS);    //�Ȳ�
		_slots.put("feet", L2Item.SLOT_FEET);    //�Ų�

		_slots.put("belt", L2Item.SLOT_BELT); //��� (����)
		_slots.put("hand", L2Item.SLOT_HAND); //����
		_slots.put("rfinger,lfinger", L2Item.SLOT_R_FINGER | L2Item.SLOT_L_FINGER);
		
		_slots.put("strider", L2Item.SLOT_STRIDER);  //����
		_slots.put("wing", L2Item.SLOT_WING);        //���
		
		//װ������ �� װ����λ�� ����
		//������ ����װ����λ
		_slots.put("knife", L2Item.SLOT_HAND);
		_slots.put("sword", L2Item.SLOT_HAND);
		_slots.put("fan", L2Item.SLOT_HAND);
		_slots.put("axe", L2Item.SLOT_HAND);
		_slots.put("claw", L2Item.SLOT_HAND);
		_slots.put("wand", L2Item.SLOT_HAND);
		
		_slots.put("breastplate", L2Item.SLOT_CHEST);
		_slots.put("pauldron", L2Item.SLOT_SHOULDER);
		_slots.put("pants", L2Item.SLOT_LEGS);
		_slots.put("shoe", L2Item.SLOT_FEET);
		_slots.put("helmet", L2Item.SLOT_HEAD);
		_slots.put("necklace", L2Item.SLOT_NECK);
		_slots.put("bracer", L2Item.SLOT_L_BRACELET);
		_slots.put("ring", L2Item.SLOT_LR_FINGER);
		_slots.put("wing", L2Item.SLOT_WING);
		
		//end
		

		_slots.put("none", L2Item.SLOT_NONE);

	}
    
    // end add
    
    //���ڵ���Ʒ���
    //������ݿ�
    private Map<Integer, Item> _itemData = new FastMap<Integer, Item>();

    /**
     * @param armorData
     * @param f
     * iDentify  1:��� 2:���� 3:���������Ʒ
     */
    public DocumentItem(Map<Integer, Item> pItemData, File file, int iDentify)
    {
        super(file);
        _itemData = pItemData;
        _iDentify = iDentify;
    }

    /**
     * @param item
     */
    private void setCurrentItem(Item item)
    {
        _currentItem = item;
    }

    @Override
    public StatsSet getStatsSet()
    {
        return _currentItem.set;
    }

    @Override
    public String getTableValue(String name)
    {
        return _tables.get(name)[_currentItem.currentLevel];
    }

    @Override
    public String getTableValue(String name, int idx)
    {
        return _tables.get(name)[idx - 1];
    }

    @Override
    public void parseDocument(Document doc)
    {
        //new 
        //�µ� ����xml�ķ���.
        NodeList itemList = doc.getElementsByTagName( "item" );
        int iLength = itemList.getLength();
        
        for( int i = 0; i < iLength; i++ )
        {
        	setCurrentItem( new Item() );
        	parseItem ( itemList.item( i ) );
        	_itemsInFile.add( _currentItem.item );
        	resetTable();
        }
        
    }
    
    // Test
    public static void main(String[] args)
    {
    	
    	File f = new File( "testItem.xml" );
    	
    	DocumentBase db = new DocumentItem(null, f , 1);
    	
    	db.parse();
    	
    	List<L2Item> itlist = ((DocumentItem)db).getItemList();
    	
    	for( L2Item it:itlist )
    	{
    		( (L2Armor)it ).testThis();
    	}
    	
    }
    
    
    /**
     * ��ȡ ��Ʒ������
     * @param n
     */
    protected void readItemType(StatsSet ss)
    {
    	if( _currentItem == null )
    	{
    		return ;
    	}
    	
//    	_currentItem.set = new StatsSet();
    	//ȷ�� ss ��new�����ġ� ���� ��Ӧ��������
    	_currentItem.set = ss;
    	
    	//iDentify  1:��� 2:���� 3:���������Ʒ
    	switch( _iDentify )
    	{
    	case 1:
    		readArmorType( ss );
    		break;
    	case 2:
    		readWeaponType( ss );
    		break;
    	case 3:
    		readEtcType( ss );
    		break;
    	}
    	
    }// end readItemType
    
    //�������
    protected void readArmorType( StatsSet ss )
    {
    	_currentItem.type = _armorTypes.get(ss.getString("itemtype"));

    	_currentItem.set.set("item_id", _currentItem.id);
    	_currentItem.set.set("name", _currentItem.name);
//
//		_currentItem.set.set("sellable", Boolean.valueOf(ss.getString("sellable")));
//		_currentItem.set.set("dropable", Boolean.valueOf(ss.getString("dropable")));
//		_currentItem.set.set("destroyable", Boolean.valueOf(ss.getString("destroyable")));
//		_currentItem.set.set("tradeable", Boolean.valueOf(ss.getString("tradeable")));
//		//�ܷ�洢 �浽�ֿ�
//		_currentItem.set.set("depositable", Boolean.valueOf(ss.getString("depositable")));
//		_currentItem.set.set("skill", ss.getString("skill")); 

		int bodypart = _slots.get(ss.getString("equiptype"));
		_currentItem.set.set("bodypart", bodypart);
		
		if (bodypart == L2Item.SLOT_NECK || (bodypart & L2Item.SLOT_L_FINGER) != 0 || (bodypart & L2Item.SLOT_R_BRACELET) != 0 || (bodypart & L2Item.SLOT_L_BRACELET) != 0) {
			_currentItem.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
			_currentItem.set.set("type2", L2Item.TYPE2_ACCESSORY);
		} else {
			_currentItem.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
			_currentItem.set.set("type2", L2Item.TYPE2_SHIELD_ARMOR);
		}

//		_currentItem.set.set("time", ss.getInteger("time"));
//		_currentItem.set.set("isofftime", ss.getBool("isofftime", false) );
//		_currentItem.set.set("price", ss.getInteger("price"));
//		
//		
//		//���� ������
//		_currentItem.set.set("stayafterdie", ss.getBool("stayafterdie", true) );
//		
//		//�Ƿ�ɺϳ�
//		_currentItem.set.set("cancomposite", ss.getBool("cancomposite", false) );
//		//�Ƿ�ɼ�
//		_currentItem.set.set("canidentify", ss.getBool("canidentify", false) );
//		//�Ƿ�����
//		_currentItem.set.set("caninscribe", ss.getBool("caninscribe", false) );
//		//�Ƿ��׷��
//		_currentItem.set.set("canstar", ss.getBool("canstar", false) );
//		//�Ƿ�ɴ��
//		_currentItem.set.set("canpunch", ss.getBool("canpunch", false) );
//		//�Ƿ����Ƕ
//		_currentItem.set.set("canmosaic", ss.getBool("canmosaic", false) );
//		//�Ƿ������
//		_currentItem.set.set("canmelt", ss.getBool("canmelt", false) );
//		//�Ƿ�ɰ�
//		_currentItem.set.set("canbinding",  ss.getBool("canbinding", false) );
//		//��װID
//		_currentItem.set.set("isset", ss.getInteger( "isset", 0 ) );
		

		if (_currentItem.type == L2ArmorType.PET) {
			if (bodypart == L2Item.SLOT_NECK) {
				_currentItem.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
				_currentItem.set.set("type2", L2Item.TYPE2_ACCESSORY);
				_currentItem.set.set("bodypart", L2Item.SLOT_NECK);
			} else {
				_currentItem.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
				_currentItem.set.set("type2", L2Item.TYPE2_PET_STRIDER);
				_currentItem.set.set("bodypart", L2Item.SLOT_CHEST);
				
			}// end  if (bodypart == L2Item.SLOT_NECK) else
			
		}// end if (_currentItem.type == L2ArmorType.PET) {
		
    } // end  readArmorType
    
    //��������
    protected void readWeaponType( StatsSet ss )
    {
    	_currentItem.type = _weaponTypes.get(ss.getString("itemtype"));

    	_currentItem.set.set("item_id", _currentItem.id);
    	_currentItem.set.set("name", _currentItem.name);

		// lets see if this is a shield
    	//���������� װ�����
		if (_currentItem.type == L2WeaponType.NONE) {
			_currentItem.set.set("type1", L2Item.TYPE1_SHIELD_ARMOR);
			_currentItem.set.set("type2", L2Item.TYPE2_SHIELD_ARMOR);
		} else {
			_currentItem.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
			_currentItem.set.set("type2", L2Item.TYPE2_WEAPON);
		}
		
		_currentItem.set.set("bodypart", _slots.get(ss.getString("equiptype")));
		
//		_currentItem.set.set("crystallizable", Boolean.valueOf(ss.getString("crystallizable")).booleanValue());
//		_currentItem.set.set("atk_speed",ss.getInteger("atk_speed"));
//
//		_currentItem.set.set("time", ss.getInteger("time"));
//		//���� �Ƿ��ʱ
//		_currentItem.set.set("isofftime", ss.getBool("isofftime", false) );
//		_currentItem.set.set("price", ss.getInteger("price"));
//		_currentItem.set.set("sellable", Boolean.valueOf(ss.getString("sellable")));
//		_currentItem.set.set("dropable", Boolean.valueOf(ss.getString("dropable")));
//		_currentItem.set.set("destroyable", Boolean.valueOf(ss.getString("destroyable")));
//		_currentItem.set.set("tradeable", Boolean.valueOf(ss.getString("tradeable")));
//		_currentItem.set.set("depositable", Boolean.valueOf(ss.getString("depositable")));
//
//		_currentItem.set.set("skill", ss.getString("skill"));
//
//		_currentItem.set.set("onCast_skill_id", ss.getInteger("onCast_skill_id", 0));
//		_currentItem.set.set("onCast_skill_lvl", ss.getInteger("onCast_skill_lvl", 0));
//		_currentItem.set.set("onCast_skill_chance",ss.getInteger("onCast_skill_chance", 0));
//
//		_currentItem.set.set("onCrit_skill_id", ss.getInteger("onCrit_skill_id", 0));
//		_currentItem.set.set("onCrit_skill_lvl", ss.getInteger("onCrit_skill_lvl", 0));
//		_currentItem.set.set("onCrit_skill_chance", ss.getInteger("onCrit_skill_chance", 0));
//		
//		//���� ������
//		_currentItem.set.set("stayafterdie", ss.getBool("stayafterdie", true) );
//		
//		//�Ƿ�ɺϳ�
//		_currentItem.set.set("cancomposite", ss.getBool("cancomposite", false) );
//		//�Ƿ�ɼ�
//		_currentItem.set.set("canidentify", ss.getBool("canidentify", false) );
//		//�Ƿ�����
//		_currentItem.set.set("caninscribe", ss.getBool("caninscribe", false) );
//		//�Ƿ��׷��
//		_currentItem.set.set("canstar", ss.getBool("canstar", false) );
//		//�Ƿ�ɴ��
//		_currentItem.set.set("canpunch", ss.getBool("canpunch", false) );
//		//�Ƿ����Ƕ
//		_currentItem.set.set("canmosaic", ss.getBool("canmosaic", false) );
//		//�Ƿ������
//		_currentItem.set.set("canmelt", ss.getBool("canmelt", false) );
//		//�Ƿ�ɰ�
//		_currentItem.set.set("canbinding",  ss.getBool("canbinding", false) );
//		//��װID
//		_currentItem.set.set("isset", ss.getInteger( "isset", 0 ) );

		if (_currentItem.type == L2WeaponType.PET) {
			_currentItem.set.set("type1", L2Item.TYPE1_WEAPON_RING_EARRING_NECKLACE);
			_currentItem.set.set("type2", L2Item.TYPE2_PET_STRIDER);

			_currentItem.set.set("bodypart", L2Item.SLOT_HAND);
		}
		
    }// end
    
    //���������Ʒ
    protected void readEtcType( StatsSet ss )
    {

    	_currentItem.set.set("item_id", _currentItem.id);
    	
    	_currentItem.set.set("type1", L2Item.TYPE1_ITEM_QUESTITEM_ADENA);
    	_currentItem.set.set("type2", L2Item.TYPE2_OTHER);
    	_currentItem.set.set("bodypart", -1);
    	
//    	_currentItem.set.set("sellable", Boolean.valueOf(ss.getString("sellable")));
//    	_currentItem.set.set("dropable", Boolean.valueOf(ss.getString("dropable")));
//    	_currentItem.set.set("destroyable", Boolean.valueOf(ss.getString("destroyable")));
//    	_currentItem.set.set("tradeable", Boolean.valueOf(ss.getString("tradeable")));
//    	_currentItem.set.set("depositable", Boolean.valueOf(ss.getString("depositable")));
//    	_currentItem.set.set("handler", ss.getString("handler"));
//    	_currentItem.set.set("skill", ss.getString("skill"));
    	
    	String itemType = ss.getString("itemtype");
    	if( itemType == null )
    	{
    		_log.warn("��Ʒ�����Ͳ����� " + _currentItem.name, Config.SERVER_ID );
//    		System.out.println(_currentItem.name);
    	}

    	_currentItem.type = _etcTypes.get(ss.getString("itemtype"));
    	if( _log.isDebugEnabled() ){
    		_log.debug("��Ʒ������:" + _currentItem.name + "-" + _currentItem.type );
    	}
		if ( itemType.equals("RedPotion") )
		{
			_currentItem.set.set("type2", L2Item.TYPE2_POTION);
		}
		else if( itemType.equals("BluePotion") )
		{
			_currentItem.set.set("type2", L2Item.TYPE2_POTION);
		}
		else if( itemType.equals("PurplePotion") )
		{
			_currentItem.set.set("type2", L2Item.TYPE2_POTION);
		}
		else if( itemType.equals("GreenPotion") )
		{
			_currentItem.set.set("type2", L2Item.TYPE2_POTION);
		}
		else if (itemType.equals("Quest")) {
			_currentItem.set.set("type2", L2Item.TYPE2_QUEST);
		}
		else if (itemType.equals("Money"))
		{
			_currentItem.set.set("type2", L2Item.TYPE2_MONEY);
		}
//		else {
//			_log.info("unknown etcitem type: {}" , itemType);
//			_currentItem.type = L2EtcItemType.OTHER;
//		}

//		String consume = ss.getString("consume_type");
//		if (consume.equals("asset")) {
//			_currentItem.type = L2EtcItemType.MONEY;
//			_currentItem.set.set("stackable", true);
//			_currentItem.set.set("type2", L2Item.TYPE2_MONEY);
//		} else if (consume.equals("stackable")) {
//			_currentItem.set.set("stackable", true);
//		} else {
//			_currentItem.set.set("stackable", false);
//		}

		_currentItem.set.set("name", _currentItem.name);

		
//		//���� ������
//		_currentItem.set.set("stayafterdie", ss.getBool("stayafterdie", true) );
//		
//		//���� �Ƿ��ʱ
//		_currentItem.set.set("isofftime", ss.getBool("isofftime", false) );
//		_currentItem.set.set("time", ss.getInteger("time"));
//		_currentItem.set.set("price", ss.getInteger("price"));
    }
    

    /**
     * ������Ʒ�ڵ�
     * @param n
     */
    protected void parseItem(Node n)
    {
    	
		 int itemId = Integer.parseInt(n.getAttributes().getNamedItem("id").getNodeValue());
	     String itemName = n.getAttributes().getNamedItem("name").getNodeValue();
    	
    	try {
      	        _currentItem.id = itemId;
    	        _currentItem.name = itemName;
    	        StatsSet itemSet = new StatsSet();     
    	        
    	        NodeList tableList = ( (Element)n ).getElementsByTagName("table"); 
    	        for( int i=0; i < tableList.getLength(); i++ )
    	        {
    	        	parseTable( tableList.item( i ) );
    	        }
    	        
    	        //��Ʒ�Ļ�����
    	        NodeList setList = ( (Element)n ).getElementsByTagName("set");
    	        for( int i=0; i < setList.getLength(); i++ )
    	        {
    	        	parseBeanSet( setList.item( i ),  itemSet, 1 );
    	        }
    	        //end ��Ʒ�Ļ�����
    	        
    	        //��Ʒ��������
    	        
    	        NodeList forList = ( (Element)n ).getElementsByTagName("for");
    	        readItemType( itemSet );
    	        makeItem();
    	        for( int i=0; i < forList.getLength(); i++ )
    	        {
    	        	parseTemplate( forList.item( i ), _currentItem.item );
    	        }
    	        
    	        //��Ʒ��Ч������(����)
    	        
    	        NodeList condList = ( (Element)n ).getElementsByTagName("cond");
    	        for( int i=0; i < condList.getLength(); i++ )
    	        {
    	        	Node condNode = condList.item( i );
    				Condition condition = parseCondition(condNode.getFirstChild(), _currentItem.item );
    				Node msg = condNode.getAttributes().getNamedItem("msg");
    				Node msgId = condNode.getAttributes().getNamedItem("msgId");
    				if (condition != null && msg != null)
    					condition.setMessage(msg.getNodeValue());
    				else if (condition != null && msgId != null)
    				{
    					condition.setMessageId(Integer.decode(getValue(msgId.getNodeValue(), null)));
    					Node addName = condNode.getAttributes().getNamedItem("addName");
    					if (addName != null && Integer.decode(getValue(msgId.getNodeValue(), null)) > 0)
    						condition.addName();
    				}
    				_currentItem.item.attach(condition);
    	        }
    	        
    	        NodeList skillList = ( (Element)n ).getElementsByTagName("skill");
    	        for( int i=0; i < skillList.getLength(); i++ )
    	        {
    	        	attachSkill( skillList.item( i ),  _currentItem.item, null );
    	        }
    	        
    	        _currentItem.item.getAllAttributString();
			
		} catch (Exception e) {
			e.printStackTrace();
//			System.out.println( "***************name:" + itemName );

		}       
        
    }// end  parseItem

    private void makeItem()
    {
    	//�����Ʒ����
        if (_currentItem.item != null) return;
        if (_currentItem.type instanceof L2ArmorType) _currentItem.item = new L2Armor(
        		(L2ArmorType) _currentItem.type, _currentItem.set);
        else if (_currentItem.type instanceof L2WeaponType) _currentItem.item = new L2Weapon(
        		(L2WeaponType) _currentItem.type, _currentItem.set);
        else if (_currentItem.type instanceof L2EtcItemType) _currentItem.item = new L2EtcItem(
        		(L2EtcItemType) _currentItem.type, _currentItem.set);
        else throw new Error("Unknown item type " + _currentItem.type + "-" + _currentItem.item.getName());
        
    }

    /**
     * @return
     */
    public List<L2Item> getItemList()
    {
        return _itemsInFile;
    }
}
